//
//  main.m
//  OC2.实例变量可见度_方法
//
//  Created by dllo on 16/2/25.
//  Copyright © 2016年 Apon. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Person.h"
#import "Student.h"

int main(int argc, const char * argv[]) {
#pragma mark - 知识点1.实例(成员)变量可见度
    /**
     *三种:@public, @protected, @private,
     *默认: @protedted.
     *
     *三种之前的区别: @public: 本类 可以直接访问(->),
                             子类 可以直接访问,
                             其他类 可以直接访问
                    @protected: 本类 可以直接访问,
                                子类 可以直接访问,
                                其他类 不可以直接访问
                    @private 本类 可以直接访问,
                             子类 可以直接访问,
                             其他类 不可以直接访问
     *详见 Person.h文件.
     */
    
#pragma mark - 知识点2.方法
    /**
     *[接受者 消息]
     *
     *接受者: 类和对象.
     *消息(方法): 类方法(+)和对象方法(-).
     *
     *详见 Person.h文件.
     */
    
    

#pragma mark - 知识点3. setter, getter 方法
    /**
     * 一个实例变量要有一对setter, getterfangfa.
     *setter方法目的,对实例变量赋值.
     *getter方法目的,对实例变量取值.
     *
     *详见: Person.h
     */
    
#if 0
    
    //创建对象.
    Person *person1 = [[Person alloc] init];
    //调用set方法.
    [person1 setName:@"zhangsan"];
    //调用get方法.
    [person1 name];
    NSString *str = [person1 name];
    NSLog(@"str:%@", str);
    
    
    //创建person2对象.
    Person * person2 = [[Person alloc] init];
    [person2 setName:@"Tom"];
    [person2 setName:@"lisi"];
    NSLog(@"%@", [person2 name]);
   //  注意: 向下面的person3并没有开辟新的内存,只是指针指向了 person 内存首地址
    Person *person3 = person2;
    NSLog(@"%@", [person3 name]);
    
    
#pragma mark - 知识点4. 继承
    /**
     * 子类继承父类 所有的实例变量和方法.
     * OC中, 只有子类和父类两层.
     * OC中是单项传递
     * 继承有传递性.
     *
     *Student类继承于Person类, collegeStudent类继承于Student类.
     *详见 Student, collegeStudent类文件.
     */
    
    // 创建学生对象,
    Student *stu1 = [[Student alloc] init];
    
    //
    [stu1 setName:@"小明"];
    [stu1 name:@"小明" sex:@"male" age:18];
    [stu1 sayHi];
    

    
#pragma mark - 知识点5. 重写父类方法(overwrite)
    /**
     * 父类方法无法满足子类需求.
     * 重写父类方法一般是在父类方法的基础上,添加的代码段,
     *
     * 详见 Student.m文件
     */
    
    
    // 创建一个student对象
    Student *student1 = [[Student alloc] init];
    
    [student1 name:@"wangwu" sex:@"male" age:20];
    [student1 setGrade:80];
    [student1 setClassroomName:@"DLS160101"];
    
    
    //调用sayHifangfa.
    [student1 sayHi];
    //[student1 sayHello];
    //Person *p1 = [[NSString alloc] init];
    ///[p1 sayHi];
    

#pragma mark - 知识点6. 重写初始化方法.

    
    /**
     *Person类重写 父类的init方法
     *详见Person.m 文件.
     *
     */
    
    // 创建person对象.
    Person *per1 = [[Person alloc] init];
    [per1 sayHi];
    
    
    
    //创建student对象
//    Student *stu1 = [[Student alloc] init];
//    [stu1 sayHi];
    
#pragma mark - 知识点7. 自定义初始化方法
  /**
   * 需求: 通过一个方法, 实现了初始化, 同时给某些实例变量赋值.
   *
   *详见 Person.h, Person.m文件
   */
    
    
    
    
    //创建person对象.
//    Person *per1 = [[Person alloc] initWithName:@"Tom"];
//    [per1 sayHi];
    
    
    
    
    Person *per2 = [[Person alloc] initWithName:@"小白" sex:@"女" age:18];
    [per2 sayHi];
#endif
    
#pragma mark - 知识点8.构造器
    /** 
     *构造器就是方法,
     * + 方法.
     * 封装了
     *
     */
    
    
    Person *per1 = [Person person];
    Person *per2 = [Person personWithName:@"Tom" sex:@"女" age:18];
    
    return 0;
}
